<?php
/*----------------------------------------------------------------------------------------------
Kit Applicatif PHP
Noyau g øn ørique d'applications PHP / generic kernel for PHP applications
noyau 0.5 / PHP 4
http://code.fredbird.org/wak

Definition de l'interface basique des composants du noyau


file version 2005-05-18 15:03:00
----------------------------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------------------------
interface primaire des  éléments du noyau
----------------------------------------------------------------------------------------------*/

class wakCoreComponent {
	// proprietes
	//var $parameters_path='cfg/';
	var $config_file;
	var $default_parameters=array();
	//var $parameters_file="param.wak-config.txt";
	// constructeur -- sauf controller
	function wakCoreComponent(& $controller) {
		$this->C=& $controller;
		$this->config_file='cfg/'.strtolower(get_class($this)).'.config.ini';
		$this->setOwnParameters();
		// api not usable at this stage
		//waklog('kernel component '.get_class($this).' created');
	}
	
	/* returns a singleton for the class
	*/
	function & getSingleton() {
		$class=__CLASS__; // getting current class name
		// instanciation unique
		if (!isset($GLOBALS['singletons'][$class])) {
			// getting arguments to forward
			$args=func_get_args();
			/* building instanciation code, forwarding arguments
			creating singleton and a single global reference per class name */
			$eval='$GLOBALS[\'singletons\'][$class]=& new $class(';
			// adding arguments to constructor
			for ($f=0; $f<count($args); $f++) $eval.='$args['.$f.'],';
			// deleting last unnecessary ',' and closing call
			if ($f>0)
				$eval=substr($eval,0,-1);
			$eval.=');'; //echo $eval;
			// executing instanciation code
			eval($eval);
		}
		// throwing instance
		return $GLOBALS['singletons'][$class];
	}
	
	// auto-parametrage
	function setOwnParameters() {
		// recup des parametres, ou parametres par defaut
		if (!$this->parameters=$this->readParameters()) {
			$this->parameters=$this->default_parameters;
		}
		$this->cfg=&$this->parameters;
		$this->config=&$this->parameters;
		$this->param=&$this->parameters;
		//echo '<br />'.get_class($this).' parameters : '.print_r($this->parameters);
	}
	
	function & readParameters() {
		$ownclass=get_class($this);
		$file=$this->config_file;
		if (!is_file($file) or !is_readable($file)) {
			// trigger_error("unable to read config file $file for ".get_class($this));
			$r=false; return $r;
		}
		$data=parse_ini_file($file,true);
		if (!$data) return false;
		if (isset($this->default_parameters)) $default=&$this->default_parameters;
		if (isset($this->default_param)) $default=&$this->default_param;
		if (isset($this->default_config)) $default=&$this->default_config;
		if (isset($this->default_cfg)) $default=&$this->default_cfg;
		$data=$this->array_merge_recursive_replace($default,$data);
		//echo affvar($data,$file);
		// echo "<p>read config file $file for ".get_class($this)."</p>";
		// print_r($data);
		// trigger_error("read parameters from $file",E_USER_NOTICE);
		return $data;
	}
	function writeParameters($array) {
		$string=$this->makeIniFile($array);
		$file=$this->config_file;
		$f=fopen($file,'wb');
		return fwrite($f,$string);
	}
	
	// recup parametres par defaut
	function getDefaultParameters() {
		if (isset($this->default_parameters)) return $this->default_parameters;
		if (isset($this->default_param)) return $this->default_param;
		if (isset($this->default_cfg)) return $this->default_cfg;
		return false;
	}
	function getParameters() {
		if (isset($this->parameters)) return $this->parameters;
		if (isset($this->cfg)) return $this->cfg;
		return false;
	}
	
	function makeIniFile($data=array()) {
		// caractère de fin de ligne : \r\n ou \n
		$endline="\r\n";
		// en-tete
		$content='; this a configuration file for the KAP '.get_class($this).' component'.$endline
		.'; see doc for php function parse_ini_file'.$endline
		.'; file version '.date('Y-m-d H:i:s').$endline;
		foreach($data as $key => $item) {
			if(is_array($item)) {
				$content.="[{$key}]".$endline;
					foreach ($item as $key2 => $item2) {
						if(is_numeric($item2) || is_bool($item2))
							$content .= "{$key2} = {$item2}".$endline;
						else
							$content .= "{$key2} = \"{$item2}\"".$endline;
					}
			} else {
				if(is_numeric($item) || is_bool($item))
					$content .= "{$key} = {$item}".$endline;
				else
					$content .= "{$key} = \"{$item}\"".$endline;
			}
		}
		return $content;
	}
	
	// fusionne deux tableaux recursivement, avec remplacement des collisions
	function & array_merge_recursive_replace(&$array_1,&$array_2) {
		$merge=$array_1;
		$keys_1=array_keys($array_1);
		$keys_2=array_keys($array_2);
		foreach ($merge as $key => $value) {
			if (!isset($array_2[$key]))
				continue;
			if (is_array($value) and is_array($array_2[$key])) {
				// appel recursif
				$merge[$key]=$this->array_merge_recursive_replace($value,$array_2[$key]);
			} else {
				$merge[$key]=$array_2[$key];
			}
		}
		foreach ($array_2 as $key => $value)
			if (!isset($merge[$key])) $merge[$key]=$value;
		return $merge;
	}
}
?>
